package ro.peoplecentric.ctc.common.dao.impl;

import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import ro.peoplecentric.ctc.common.dao.ItemDao;
import ro.peoplecentric.ctc.common.entity.Item;
import ro.peoplecentric.ctc.common.util.ui.ItemCriteria;

/**
 * {@link ItemDao } implementation.
 *
 * @author pguzun
 */
@Repository
public class ItemDaoImpl extends BaseDaoImpl implements ItemDao {

	private static final String DEFAULT_SORTING_ORDER = "asc";
	private static final String DEFAULT_SORTING_COLUMN = "title";

    /**
     * @inheritDocs
     */
    @Override
    public List<Item> getAll() {
        final Criteria criteria = getSession().createCriteria(Item.class);
        criteria.addOrder(Order.asc("title"));
        return criteria.list();
    }

    /**
     * @inheritDocs
     */
    @Override
    public List<Item> getLastModifiedItems() {
        final Criteria criteria = getSession().createCriteria(Item.class);
        criteria.addOrder(Order.desc("addedDate"));
        criteria.setMaxResults(MAX_LAST_MODIFIED_ITEMS);
        return criteria.list();
    }

    /**
     * @inheritDocs
     */
    @Override
    public List<Item> find(ItemCriteria itemCriteria) {
        final Criteria criteria = getSession().createCriteria(Item.class);
        criteria.createAlias("region", "region");
        criteria.createAlias("category", "category");
        if (!StringUtils.isEmpty(itemCriteria.getSearchValue())) {
            final Disjunction or = Restrictions.disjunction();
            //anywhere
            or.add(Restrictions.ilike("title", itemCriteria.getSearchValue(), MatchMode.ANYWHERE));
            or.add(Restrictions.ilike("description", itemCriteria.getSearchValue(), MatchMode.ANYWHERE));
            //start With
            or.add(Restrictions.ilike("postalCode", itemCriteria.getSearchValue(), MatchMode.START));
            or.add(Restrictions.ilike("name", itemCriteria.getSearchValue(), MatchMode.START));
            or.add(Restrictions.ilike("email", itemCriteria.getSearchValue(), MatchMode.START));
            or.add(Restrictions.ilike("phone", itemCriteria.getSearchValue(), MatchMode.START));
            or.add(Restrictions.ilike("region.name", itemCriteria.getSearchValue(), MatchMode.START));
            or.add(Restrictions.ilike("category.name", itemCriteria.getSearchValue(), MatchMode.START));
            criteria.add(or);
        }

        criteria.addOrder(Order.asc("title"));
        return criteria.list();
    }

    /**
     * Gets default order by which fetching entity list must be sorted.
     *
     * @return Order
     */
    @Override
    protected Order getDefaultOrderBy() {
        return Order.asc("id");
    }

    @SuppressWarnings("unchecked")
	@Override
	public List<Item> getAllItems(String order, String orderBy) {
		final Criteria criteria = getSession().createCriteria(Item.class);
		String sortingOrder = DEFAULT_SORTING_ORDER;
		if (order != null && !order.isEmpty()) {
			sortingOrder = order;
		}
		String sortingColumn = DEFAULT_SORTING_COLUMN;
		if (orderBy != null && !orderBy.isEmpty()) {
			sortingColumn = orderBy;
		}
		if (sortingOrder.equals(DEFAULT_SORTING_ORDER)) {
			criteria.addOrder(Order.asc(sortingColumn));
		}
		else {
			criteria.addOrder(Order.desc(sortingColumn));
		}
        return criteria.list();
	}
}
